home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
TEX-UTIL
/
TR2LATEX
/
c
/
subs
(
.txt
)
next >
Wrap
LaTeX Document
|
1992-04-27
|
20KB
|
753 lines
** tr2latex - troff to LaTeX converter
** $Id: subs.c,v 2.2 1992/04/27 15:13:26 Christian_Engel Dist krischan $
** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel
** Module: subs.c
** These subroutines do (in general) small things for the translator.
** They appear in alphabetical order and their names are unique in the
** first six characters.
#include "setups.h"
#include "protos.h"
#include "simil.h"
#include "greek.h"
#include "flip.h"
#include "forbid.h"
#include "maths.h"
#include "macros.h"
extern def_count;
extern mydef_count;
/* compile-time counting of elements */
int GRK_count = (sizeof(GRK_list)/sizeof(GRK_list[0]));
int sim_count = (sizeof(sim_list)/sizeof(sim_list[0]));
int flip_count = (sizeof(flip_list)/sizeof(flip_list[0]));
int forbd_count = (sizeof(forbid)/sizeof(forbid[0]));
int mathcom_count = (sizeof(math)/sizeof(struct math_equiv));
int macro_count = (sizeof(macro)/sizeof(struct macro_table));
** alternate fonts (manual macro)
char *alternate (char *pin, char *pout, char *w)
int which = 1;
char font[MAXWORD], font1[MAXWORD], font2[MAXWORD],
ww[MAXWORD], tmp[MAXWORD];
tmp[0] = EOS;
switch (w[1]) {
case 'R': strcpy (font1,"\\rm"); break;
case 'I': strcpy (font1,"\\it"); break;
case 'B': strcpy (font1,"\\bf"); break;
switch (w[2]) {
case 'R': strcpy (font2,"\\rm"); break;
case 'I': strcpy (font2,"\\it"); break;
case 'B': strcpy (font2,"\\bf"); break;
strcpy (font, font1);
while (*pin != '\n' && *pin != EOS) {
pin += get_arg (pin, ww, 1);
if (which == 1) {
sprintf(tmp,"{%s %s}", font1, ww);
which = 2;
else {
sprintf (tmp,"{%s %s}", font2, ww);
which = 1;
pout = strapp (pout, tmp);
while (*pin == ' ' || *pin == '\t')
pin++;
return (pout);
** check if w is in the GREEK list
int CAP_GREEK (char *w)
int i;
for (i = 0; i < GRK_count; i++) {
if (strcmp (GRK_list[i], w) == 0)
return (1);
return (-1);
** translate table
** arguments:
** pin
** pout
** offset amount to offset pin
char *do_table (char *pin, char *pout, int *offset)
char w [MAXWORD], ww [MAXWORD], format [MAXWORD], tmp [MAXWORD];
char *ptr;
int i, len, columns=0;
int tab = '\t'; /* default tab */
tmp[0] = EOS;
ptr = pin; /* remember where we started */
len = get_line (pin, w, 0);
if (w [strlen (w) - 1] == ';') { /* options */
pin += len;
if (strncmp (w, "tab", 3) == 0) /* get the tab charecter */
tab = w[4]; /* expect something like tab(&); */
pin = skip_line(pin);
while (*pin != EOS) { /* get the LAST format line */
len = get_line (pin, w, 0);
if (w[strlen (w) - 1] != '.') /* not a format line */
break;
pin += len;
for (i = 0; i < len - 1; i++) {
if (isspace (w[i]))
continue;
if (w[i] == 'l')
format[columns] = 'l';
else if (w[i] == 'r')
format[columns] = 'r';
else
format[columns] = 'c';
columns++;
if (columns == 0) {
fprintf (stderr, "Sorry, I cannot do tables without a format line\n\
Doing plain translation of table, lines will be commented\n\
You need to fix it yourself\n");
while (*pin != EOS) {
(void) getword (pin, w);
if (strcmp (w,".TE") == 0) {
pin += 4;
break;
pin += get_line (pin, w, 1);
*pout++ = '%';
pout = strapp (pout, w);
pout = strapp (pout, "\n");
pin++; /* skip the \n */
*offset = pin - ptr;
return (pout);
format[columns] = EOS;
sprintf (tmp, "\\par\n\\begin{tabular}{%s}\n",format);
pout = strapp (pout, tmp);
while (*pin != EOS) {
for (i = 0; i < columns - 1; i++) {
(void) getword (pin, w);
if (i == 0 && (strcmp (w, "\n") == 0 || strcmp (w, "_") == 0)) {
pin++;
i--;
continue;
if (strcmp (w, ".TE") == 0) {
pin += 4;
if (i == 0) {
pout -= 3; /* take back the \\ and the \n */
*pout = EOS;
}
pout = strapp(pout,"\n\\end{tabular}\n\\par\n");
*offset = pin - ptr;
return (pout);
pin += get_table_entry(pin,w,tab);
pin ++; /* skip tab */
troff_tex(w,ww,0,1);
sprintf(tmp,"%s & ",ww);
pout = strapp(pout,tmp);
(void) getword (pin,w);
if (strcmp(w,".TE") == 0) {
fprintf(stderr,"Oops! I goofed. I told I you I am not very good at tables\nI've encountered an unexpected end for the table\n\
You need to fix it yourself\n");
pin += 4;
pout = strapp(pout,"\\end{tabular}\n\\par\n");
*offset = pin - ptr;
return(pout);
pin += get_table_entry(pin,w,'\n');
pin++; /* skip tab */
troff_tex(w,ww,0,1);
pout = strapp (pout, ww);
pout = strapp (pout, "\\\\\n");
fprintf (stderr, "Oops! I goofed. I told I you I am not very good at tables\n\
File ended and I haven't finished the table!\n\
You need to fix it yourself\n");
*offset = pin - ptr;
pout = strapp (pout, "\\end{tabular}\n\\par\n");
return (pout);
** end current environment
char *end_env (char *pout)
if (IP_stat) {
IP_stat = 0;
pout = strapp (pout, "\\end{IPlist}");
if (QP_stat) {
QP_stat = 0;
pout = strapp (pout, "\\end{quotation}");
if (TP_stat) {
TP_stat = 0;
pout = strapp (pout, "\\end{TPlist}");
return(pout);
** set flag for current environment
void envoke_stat (int par)
switch(par) {
case 2:
IP_stat = 1;
break;
case 3:
TP_stat = 1;
break;
case 4:
QP_stat = 1;
break;
default:
break;
** do the flipping
char * flip (char *pout, char *w)
int lb=0, rb=0;
char ww[MAXWORD], tmp[MAXWORD];
ww[0] = EOS;
tmp[0] = EOS;
pout--;
while (isspace (*pout))
pout--;
while (1) {
if (*pout == '{') {
lb++;
if (lb > rb)
break;
if (*pout == '}')
rb++;
if (rb == 0) {
if (! isspace (*pout) && *pout != '$') {
pout--;
continue;
else
break;
pout--;
if (lb == rb && lb != 0)
break;
pout++;
if (*pout == '\\') {
pout++;
(void) getword (pout, tmp);
sprintf (ww, "\\%s", tmp);
pout--;
else if (*pout == '{')
(void) get_brace_arg (pout, ww);
else
(void) getword (pout, ww);
*pout = EOS;
sprintf (tmp,"\\%s %s", w, ww);
pout = strapp (pout, tmp);
return (pout);
** take care of things like x hat under
char * flip_twice (char *pout, char *w, char *ww)
int lb=0, rb=0;
char tmp1[MAXWORD], tmp2[MAXWORD];
tmp1[0] = EOS; tmp2[0] = EOS;
pout--;
while (*pout == ' ' || *pout == '\t' || *pout == '\n')
pout--;
while (1) {
if (*pout == '{') {
lb++;
if (lb > rb)
break;
if (*pout == '}')
rb++;
if (rb == 0) {
if (! isspace (*pout) && *pout != '$') {
pout--;
continue;
else
break;
pout--;
if (lb == rb && lb != 0)
break;
pout++;
if (*pout == '\\') {
pout++;
(void) getword(pout,tmp2);
sprintf(tmp1,"\\%s",tmp2);
pout--;
else if (*pout == '{')
(void) get_brace_arg(pout,tmp1);
else
(void) getword(pout,tmp1);
*pout = EOS;
sprintf(tmp2,"\\%s{\\%s %s}",w,ww,tmp1);
pout = strapp(pout,tmp2);
return(pout);
** get argument
** arguments:
** rec=1 means recursive
int get_arg (register char *pin, char *w, int rec)
int c,len,i;
char ww[MAXWORD];
int delim;
len=0;
while ((c = *pin) == ' ' || c == '\t') { /* skip spaces and tabs */
pin++;
len++;
i=0;
if (*pin == '{' || *pin == '\"') {
if (*pin == '{')
delim = '}';
else
delim = '\"';
pin++;
len++;
while ((c = *pin++) != EOS && c != delim && i < MAXWORD) {
if (c == ' ' && delim == '\"')
ww[i++] = '\\';
ww[i++] = (char)c;
len++;
len++;
else {
while ((c = *pin++) != EOS && !isspace(c)
/* && c != '$' && c != '}' */ && i < MAXWORD) {
if (math_mode && c == '~')
break;
ww[i++] = (char)c;
len++;
ww[i] = EOS;
if (rec == 1) /* check if recursion is required */
troff_tex(ww,w,1,1);
else
strcpy(w,ww);
return(len);
** get all arguments
** arguments:
** rec=1 means recursive
int get_allargs (register char *pin, char ***ppw, int rec)
int c, i;
static char *ww [MAXARGS];
char w [MAXWORD], *instart;
int nww;
int delim;
instart = pin;
for (nww = 0; ; nww++) {
while ((c = *pin) == ' ' || c == '\t') /* skip spaces and tabs */
pin++;
if (c == '\n') {
pin++;
ww [nww] = EOS;
break;
ww [nww] = pin;
i=0;
if (*pin == '{' || *pin == '\"') {
if (*pin == '{')
delim = '}';
else
delim = '\"';
ww [nww] = ++pin;
while ((c = *pin++) != EOS && c != delim && i < MAXWORD)
/* EMPTY */
;
pin [-1] = EOS;
else {
while ((c = *pin++) != EOS && !isspace(c)
/* && c != '$' && c != '}' */ && i < MAXWORD) {
if (math_mode && c == '~')
break;
pin [-1] = EOS;
if (c == '\n') {
ww [nww + 1] = EOS;
break;
if (rec == 1) { /* check if recursion is required */
for (i = 0; ww [i]; i++) {
if (ww [i] && *ww [i]) {
troff_tex (ww [i], w, 1, 1);
if (strcmp (ww [i], w) != 0)
ww [i] = strsave (w);
*ppw = ww;
return (pin - instart);
** get argument surrounded by braces
void get_brace_arg (char *buf, char *w)
int c,i, lb=0, rb=0;
i=0;
while ((c = *buf++) != EOS) {
w[i++] = (char)c;
if (c == '{') lb++;
if (c == '}') rb++;
if (lb == rb) break;
w[i] = EOS;
** get "define" or .de word
** arguments:
** pin delimited by space only
** w delimited by space only
int get_defword (char *pin, char *w, int *illegal)
int c,i;
*illegal = 0;
for (i=0; (c = *pin++) != EOS && !isspace (c) && i < MAXWORD; i++) {
w[i] = (char)c;
if (isalpha(c) == 0)
*illegal = 1; /* illegal TeX macro */
w[i] = EOS;
if (*illegal == 0 && is_forbid(w) >= 0)
*illegal=1;
return(i);
** get the rest of the line
** arguments:
** rec=1 means recursion is required
int get_line (char *pin, char *w, int rec)
int c,i,len;
char ww[MAXLINE];
i=0;
len=0;
while ((c = *pin++) != EOS && c != '\n' && len < MAXLINE) {
ww[i++] = (char)c;
len++;
ww[i] = EOS;
if (rec == 1)
troff_tex(ww,w,0,1);
else
strcpy(w,ww);
return(len);
** get multi-line argument
int get_multi_line (char *pin, char *w)
int len=0,l=0,lines=0;
char tmp[MAXWORD];
int c1,c2;
w[0] = EOS; tmp[0] = EOS;
while (*pin != EOS) {
c1 = *pin;
c2 = *++pin;
--pin;
if (c1 == '.' && isupper(c2))
break;
lines++;
if (lines > 1)
strcat(w," \\\\\n");
l = get_line(pin,tmp,1);
strcat(w,tmp);
len += l+1;
pin += l+1;
len--;
pin--;
return(len);
** get the macro substitution
int get_mydef (char *pin, char *w)
int c1,c2,l,len;
char tmp[MAXWORD];
tmp[0] = EOS;
len=1;
while (*pin != EOS) {
c1 = *pin;
c2 = *++pin;
--pin;
if (c1 == '.' && c2 == '.')
break;
l = get_line(pin,tmp,1);
strcat(w,tmp);
len += l+1;
pin += l+1;
return(len);
** get N lines
int get_N_lines (char *pin, char *w, int N)
int len=0,l=0,lines=0;
char tmp[MAXWORD];
w[0] = EOS; tmp[0] = EOS;
while (*pin != EOS && lines < N) {
lines++;
if (lines > 1)
strcat(w," \\\\\n");
l = get_line(pin,tmp,1);
strcat(w,tmp);
len += l+1;
pin += l+1;
len--;
pin--;
return(len);
** get text surrounded by quotes in math mode
int get_no_math (char *pin, char *w)
int c,i,len;
len = 0;
for (i=0; (c = *pin++) != EOS && c != '\"' && i < MAXWORD; i++) {
if (c == '{' || c == '}') {
w[i] = '\\';
w[++i] = (char)c;
else
w[i] = (char)c;
len++;
w[i] = EOS;
return(len);
** get the denominator of over
char *get_over_arg (char *pin, char *ww)
char w[MAXWORD], tmp1[MAXWORD], tmp2[MAXWORD];
int len;
w[0] = EOS;
tmp1[0] = EOS;
tmp2[0] = EOS;
pin += getword (pin,tmp1); /* read first word */
pin += skip_white (pin);
len = getword (pin, tmp2); /* read second word */
strcat(w,tmp1); strcat(w," ");
/* as long as there is a sup or sub read the next two words */
while (strcmp (tmp2, "sub") == 0 || strcmp (tmp2, "sup") == 0) {
pin += len;
strcat (w, tmp2);
strcat (w, " ");
pin += skip_white (pin);
pin += getword (pin, tmp1);
strcat (w, tmp1);
strcat (w, " ");
pin += skip_white (pin);
len = getword (pin, tmp2);
troff_tex (w, ww, 0, 1);
return (pin);
** get reference
int get_ref (char *pin, char *w)
int len=0, l=0, lines=0;
char tmp[MAXWORD];
w[0] = EOS; tmp[0] = EOS;
while (*pin != EOS) {
if (*pin == '\n')
break;
(void) getword(pin,tmp);
if (tmp[0] == '.' && isupper(tmp[1])) {
/* these commands don't cause a break in reference */
if (strcmp (tmp, ".R") != 0 && strcmp (tmp, ".I") != 0
&& strcmp(tmp,".B") != 0)
break;
else if (tmp[0] == '.' && !(isupper(tmp[1]))) {
/* these commands don't cause a break in reference */
if (strcmp (tmp, ".br") != 0 && strcmp (tmp, ".bp") != 0)
break;
l = get_line (pin, tmp, 1);
lines++;
if (lines > 1)
strcat (w, " ");
strcat (w, tmp);
len += l+1;
pin += l+1;
len--;
pin--;
return (len);
void get_size (char *ww, struct measure *PARAMETER)
int sign=0, units=0;
float value;
if (ww[0] == EOS) {
if (PARAMETER->def_value == 0) {
PARAMETER->value = PARAMETER->old_value;
strcpy(PARAMETER->units,PARAMETER->old_units);
else {
PARAMETER->value = PARAMETER->def_value;
strcpy(PARAMETER->units,PARAMETER->def_units);
else {
PARAMETER->old_value = PARAMETER->value;
strcpy (PARAMETER->old_units, PARAMETER->units);
parse_units (ww, &sign, &units, &value);
if (units == 'p')
strcpy (PARAMETER->units, "pt");
else if (units == 'i')
strcpy (PARAMETER->units, "in");
else if (units == 'c')
strcpy (PARAMETER->units, "cm");
else if (units == 'm')
strcpy (PARAMETER->units, "em");
else if (units == 'n') {
value = .5*value; /* n is about half the width of m */
strcpy (PARAMETER->units, "em");
else if (units == 'v')
strcpy(PARAMETER->units,"ex");
else if (units == 0) {
if (sign == 0 || PARAMETER->old_units[0] == EOS)
strcpy(PARAMETER->units,PARAMETER->def_units);
else
strcpy(PARAMETER->units,PARAMETER->old_units);
else {
fprintf(stderr,"unknown units %c, using default units\n", units);
strcpy(PARAMETER->units,PARAMETER->def_units);
if (sign == 0)
PARAMETER->value = value;
else
PARAMETER->value = PARAMETER->old_value + sign*value;
** get the rest of the line -- Nelson Beebe
** arguments:
** rec=1 means recursion is required
int get_string (char *pin, char *w, int rec)
register int c,i,len;
char ww[MAXLINE];
register char *start;
if (*pin != '\"')
return(get_line(pin,w,rec));
start = pin; /* remember start so we can find len */
i=0;
pin++; /* point past initial quote */
while ((c = *pin++) != EOS && c != '\"' && c != '\n' && i < MAXLINE)
ww[i++] = (char)c;
ww[i] = EOS;
if (c != '\n') /* flush remainder of line */
while ((c = *pin++) != '\n')
/* EMPTY */
len = pin - start - 1; /* count only up to NL, not past */
if (rec == 1)
troff_tex(ww,w,0,1);
else
strcpy(w,ww);
return(len);
** get the argument for sub and sup
int get_sub_arg (char *pin, char *w)
int c,len,i;
char ww[MAXWORD], tmp[MAXWORD];
len=0; tmp[0] = EOS;
while ((c = *pin) == ' ' || c == '\t') {
pin++;
len++;
i=0;
while ((c = *pin++) != EOS && c != ' ' && c != '\t' && c != '\n'
&& c != '$' && c != '}' && c != '~' && i < MAXWORD) {
ww[i++] = (char)c;
len++;
ww[i] = EOS;
if (strcmp(ww,"roman") == 0 || strcmp(ww,"bold") == 0
|| strcmp(w,"italic") == 0) {
(void) get_arg(pin,tmp,0);
sprintf(ww,"%s%c%s",ww,c,tmp);
len += strlen(tmp)+1;
troff_tex(ww,w,0,1); /* recursive */
return(len);
int get_table_entry (char *pin, char *w, int tab)
int c, i=0;
for (i=0; (c = *pin++) != EOS && c != tab && i < MAXWORD; i++)
w[i] = (char)c;
w[i] = EOS;
return(i);
** get characters till the next space
int get_till_space (char *pin, char *w)
int c,i;
for (i=0; (c = *pin++) != EOS && c != ' ' && c != '\n'
&& c != '\t' && i < MAXWORD; i++)
w[i] = (char)c;
w[i] = EOS;
return(i);
** get the define substitution
int getdef (char *pin, char *ww)
int c,i,len;
int def_delim;
char w[MAXWORD];
def_delim = *pin++; /* take first character as delimiter */
len=1;
i=0;
while ((c = *pin++) != EOS && c != def_delim && i < MAXWORD) {
len++;
w[i++] = (char)c;
w[i] = EOS;
len++;
if (c != def_delim) {
fprintf(stderr,
"WARNING: missing right delimiter in define, define=%s\n",w);
len--;
troff_tex(w,ww,0,1); /* now translate the substitution */
return(len);
** get an alphanumeric word (dot also)
int getword (char *pin, char *w)
int c,i;
for (i=0; (c = *pin++) != EOS
&& (isalpha(c) || isdigit(c) || c == '.') && i < MAXWORD; i++)
w[i] = (char)c;
if (i == 0 && c != EOS)
w[i++] = (char)c;
w[i] = EOS;
return(i);
** change GREEK to Greek
void GR_to_Greek (char *w, char *ww)
*ww++ = '\\';
*ww++ = *w;
while(*++w != EOS)
*ww++ = tolower(*w);
*ww = EOS;
** check if w was defined by the user
int is_def (char *w)
int i;
for (i=0; i < def_count; i++) {
if (strcmp(def[i].def_macro,w) == 0)
return(i);
return(-1);
** check if w is in the flip list
int is_flip (char *w)
int i;
for (i=0; i < flip_count; i++) {
if (strcmp(flip_list[i],w) == 0)
return(i);
return(-1);
** check if w is one of those sacred macros
int is_forbid (char *w)
int i;
for (i=0; i < forbd_count; i++) {
if (strcmp(forbid[i],w) == 0)
return(i);
return(-1);
** check if w has a simple correspondence in TeX
int is_mathcom (char *w, char *ww)
int i;
for (i = 0; i < mathcom_count; i++)
if (strcmp (math[i].troff_symb, w) == 0) {
strcpy (ww, math[i].tex_symb);
return (i);
return (-1);
** check if w is user-defined macro
int is_mydef (char *w)
int i;
for (i=0; i < mydef_count; i++) {
if (strcmp(mydef[i].def_macro,w) == 0)
return(i);
return(-1);
** check if w is a macro or plain troff command
int is_troff_mac (char *w, char *ww, int *arg, int *par)
int i;
for (i=0; i < macro_count; i++)
if (strcmp(macro[i].troff_mac,w) == 0) {
strcpy(ww,macro[i].tex_mac);
*arg = macro[i].arg;
*par = macro[i].macpar;
return(i);
return(-1);
void parse_units (char *ww, int *sign, int *units, float *value)
int len, k=0, i;
char tmp[MAXWORD];
len = strlen(ww);
if (ww[0] == '-')
*sign = -1;
else if (ww[0] == '+')
*sign = 1;
if (*sign != 0)
k++;
i=0;
while (k < len) {
if (isdigit(ww[k]) || ww[k] == '.')
tmp[i++] = ww[k++];
else
break;
tmp[i] = EOS;
sscanf(tmp,"%f",value);
i=0;
if (k < len) {
*units = ww[k++];
if (k < len)
fprintf(stderr, "Suspect problem in parsing %s, unit used is %c\n",
ww, *units);
** check if w is in the similar list
int similar (char *w)
int i;
for (i=0; i < sim_count ; i++) {
if (strcmp(sim_list[i],w) == 0)
return(1);
return(-1);
** ignore the rest of the line
char * skip_line (char *pin)
while (*pin != '\n' && *pin != EOS)
pin++;
if (*pin == EOS)
return(pin);
else
return(++pin);
** skip white space
int skip_white (char *pin)
int c,len=0;
while ((c = *pin++) == ' ' || c == '\t' || c == '\n')
len++;
return(len);
** copy tail[] to s[], return ptr to terminal EOS in s[]
char * strapp (register char *s, register char *tail)
while ((*s++ = *tail++) != 0)
#ifdef DEBUG
if (debug_o)
putchar (s[-1]);
#else
/*EMPTY*/
#endif
return (s-1); /* pointer to EOS at end of s[] */
** copy input to buffer, buffer holds only MAXLEN characters
void tmpbuf (FILE *in, char *buffer)
int c;
unsigned int l=0;
while (l++ < MAXLEN && (c = getc(in)) != EOF)
*buffer++ = (char) c;
if (l >= MAXLEN) {
fprintf (stderr,"Sorry: document is too large\n");
exit(-1);
*buffer = EOS;
** save a string by allocating space
char *strsave (char *s)
char *res;
if ((res = malloc (strlen (s) + 1)) == NULL) {
fprintf (stderr, "strsave: Can't allocate %d bytes\n", strlen(s) + 1);
errexit (errno);
strcpy (res, s);
return (res);